#include <QHash>
#include <QMutex>

#include "QRemoteObject2Meta_P.h"

struct QRemoteObject2Meta::Private{


    QMutex m_mutex;
    QHash<QString,QRemoteObject2::RemoteObjectMetaDataPtr> m_datas;
};

QRemoteObject2Meta *QRemoteObject2Meta::Instance()
{
    static QRemoteObject2Meta i;
    return &i;
}

QRemoteObject2::RemoteObjectMetaDataPtr QRemoteObject2Meta::fetchRemoteClass(QString className)
{
    QMutexLocker locker(&_P->m_mutex);
    if(_P->m_datas.contains(className))
    {
        return _P->m_datas[className];
    }
    return {};
}

QList<int> QRemoteObject2Meta::allMethodData(QString className)
{
    QList<int> ret;
    QMutexLocker locker(&_P->m_mutex);
    if(_P->m_datas.contains(className))//只有注册了的能查出远程信息
    {
        auto tempData = _P->m_datas[className];
        auto tempMeta = tempData->meta;
        while (tempMeta) {
            if(tempData)
            {
                for(auto i:tempData->methods)
                {
                    ret << i.second.index;
                }
            }

            tempMeta = tempMeta->superClass();
            if(!tempMeta) break;
            tempData = _P->m_datas.value(tempMeta->className());
        }
    }

    return ret;
}

QRemoteObject2::ROMethodMetaData QRemoteObject2Meta::findMethodData(QString className, int index)
{
    QMutexLocker locker(&_P->m_mutex);
    if(_P->m_datas.contains(className))//只有注册了的能查出远程信息
    {
        auto tempData = _P->m_datas[className];
        auto tempMeta = tempData->meta;
        while (true) {
            if(tempMeta->methodOffset() <= index)
            {
                return tempData->methods[index];
            }

            tempMeta = tempMeta->superClass();
            if(!tempMeta) break;
            tempData = _P->m_datas.value(tempMeta->className());
        }
    }

    return {};
}

QList<int> QRemoteObject2Meta::allPropData(QString className)
{
    QList<int> ret;
    QMutexLocker locker(&_P->m_mutex);
    if(_P->m_datas.contains(className))//只有注册了的能查出远程信息
    {
        auto tempData = _P->m_datas[className];
        auto tempMeta = tempData->meta;
        while (tempMeta) {
            if(tempData)
            {
                for(auto i:tempData->propertys)
                {
                    ret << i.second.index;
                }
            }

            tempMeta = tempMeta->superClass();
            if(!tempMeta) break;
            tempData = _P->m_datas.value(className);
        }
    }

    return ret;
}

QRemoteObject2::ROPropertyMetaData QRemoteObject2Meta::findPropData(QString className, int index)
{
    QMutexLocker locker(&_P->m_mutex);
    if(_P->m_datas.contains(className))//只有注册了的能查出远程信息
    {
        auto tempData = _P->m_datas[className];
        auto tempMeta = tempData->meta;
        while (tempMeta) {
            if(tempMeta->propertyOffset() <= index)
            {
                return tempData->propertys[index];
            }

            tempMeta = tempMeta->superClass();
            if(!tempMeta) break;
            tempData = _P->m_datas.value(tempMeta->className());
        }
    }

    return {};
}

bool QRemoteObject2Meta::isRegistered(QString className)
{
    QMutexLocker locker(&_P->m_mutex);
    return _P->m_datas.contains(className);
}

void QRemoteObject2Meta::registerRemoteClass(QRemoteObject2::RemoteObjectMetaDataPtr meta)
{
    QMutexLocker locker(&_P->m_mutex);
    _P->m_datas[meta->meta->className()] = meta;
}

QRemoteObject2Meta::QRemoteObject2Meta():_P(new Private)
{

}

QRemoteObject2Meta::~QRemoteObject2Meta()
{

}
